/**
 * Copyright 2005 The Apache Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.edi.db.manager;

import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.edi.db.EdiCallableStatement;
import com.edi.db.PreparedEql;
import com.edi.db.TransactionWrapper;
import com.edi.db.dao.EdiDAO;
import com.edi.db.dao.EdiDAOException;
import com.edi.db.table.TableEntity;
import com.edi.db.util.DAOUtil;
import com.edi.db.util.SessionUtil;

public class DBManager {
	private static final Log log = LogFactory.getLog(DBManager.class);
	protected String appName;

	public DBManager(String appName) {
		//System.out.println("--------------appName : "+appName);
		this.appName = appName;
	}

	public TableEntity queryEql(String eql,int start,int pageSize) throws Exception {
		if (eql == null || eql.trim().equals(""))
			return null;

		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		return dao.queryEql(eql,start,pageSize);
	}
	
	public TableEntity queryEql(String eql)throws Exception {
		if (eql == null || eql.trim().equals(""))
			return null;

		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		return dao.queryEql(eql);
	}

	public TableEntity querySql(String sql,int start,int pageSize) throws Exception {
		if (sql == null || sql.trim().equals(""))
			return null;

		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		return dao.querySql(sql,start,pageSize);
	}
	
	public TableEntity querySql(String sql)throws Exception{
		if (sql == null || sql.trim().equals(""))
			return null;

		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		return dao.querySql(sql);
	}

	/**
	 * 执行eql
	 * 
	 * @param eql
	 * @param appName
	 * @return
	 */
	public boolean executeEql(String eql) {
		boolean success = false;
		if (eql == null || eql.trim().equals(""))
			return false;
		try {
			EdiDAO dao = DAOUtil.getEdiDAO(appName);
			dao.excuteEql(eql);
			success = true;
		} catch (EdiDAOException e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return success;
	}

	/**
	 * 创建表
	 * 
	 * @param tableEntity
	 * @param appName
	 * @return
	 */
	public boolean createTable(TableEntity tableEntity) {
		boolean success = false;
		if (tableEntity == null)
			return false;

		try {
			EdiDAO dao = DAOUtil.getEdiDAO(appName);
			dao.createTable(tableEntity);
			success = true;
			log.debug(" success ="+success);
		} catch (EdiDAOException e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return success;
	}

	/**
	 * 执行sql
	 * 
	 * @param sql
	 * @param appName
	 * @return
	 */
	public boolean executeSql(String sql) {
		boolean success = false;
		if (sql == null || sql.trim().equals(""))
			return false;
		try {
			EdiDAO dao = DAOUtil.getEdiDAO(appName);
			dao.excuteSql(sql);
			success = true;
		} catch (EdiDAOException e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return success;
	}

	/**
	 * 保存表
	 * 
	 * @param entity
	 * @param appName
	 * @return
	 */
	public boolean save(TableEntity entity) {
		boolean success = false;
		if (entity.getRows().size() == 0)
			return true;
		try {
			EdiDAO dao = DAOUtil.getEdiDAO(appName);
			dao.save(entity);
			success = true;
		} catch (EdiDAOException e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return success;
	}

	public void commitTables(Map<String, TableEntity> tableMaps)
			throws EdiDAOException {
		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		dao.commitTables(tableMaps);
	}

	/**
	 * 更新表
	 * 
	 * @param entity
	 * @param appName
	 * @return
	 */
	public boolean update(TableEntity entity) {
		boolean success = false;
		if (entity.getRows().size() == 0)
			return true;
		try {
			EdiDAO dao = DAOUtil.getEdiDAO(appName);
			dao.update(entity);
			success = true;
		} catch (EdiDAOException e) {
			log.error(e.getMessage());
			e.printStackTrace();
		}
		return success;
	}

	/**
	 * 执行预处理查询
	 * @param preparedEql
	 * @return
	 * @throws EdiDAOException
	 */
	public TableEntity queryPreparedEql(PreparedEql preparedEql)
			throws EdiDAOException {
		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		return dao.queryPreparedEql(preparedEql);

	}
	
	/**
	 * 返回数据库链接session
	 * @return
	 */
	public SessionUtil getSession()throws EdiDAOException{
		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		SessionUtil s = null;
		return dao.getSessionUtil();
	}
	
	/**
	 * 执行一个存储过程
	 * @param proc
	 * @throws EdiDAOException
	 */
	public Map<Integer,Object> executeProc(EdiCallableStatement proc)throws EdiDAOException{
		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		return dao.executeProc(proc);
	}
	
	/**
	 * 执行具有返回结果集的存储过程
	 * @param proc
	 * @return
	 * @throws EdiDAOException
	 */
	public TableEntity queryProc(EdiCallableStatement proc)throws EdiDAOException{
		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		return dao.queryProc(proc);
	}
	
	/**
	 * 执行具有返回结果集和输出参数的存储过程
	 * @param proc
	 * @param outParamValues
	 * @return
	 * @throws EdiDAOException
	 */
	public TableEntity queryProc(EdiCallableStatement proc,Map<Integer,Object> outParamValues)throws EdiDAOException{
		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		return dao.queryProc(proc,outParamValues);
	}

	public boolean executePreparedEql(PreparedEql preparedEql)
			throws EdiDAOException {
		boolean success = false;
		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		dao.executePreparedEql(preparedEql);
		success = true;
		return success;
	}
	
	public void execTansaction(List<TransactionWrapper> transactionWrappers)throws EdiDAOException{
		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		dao.execTansaction(transactionWrappers);
	}
	public boolean hasTable(String appName ,String tableName)throws EdiDAOException{
		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		return dao.hasTable(tableName);
	}
	
	public int getResultSetRowsCount(String eql) throws EdiDAOException{
		eql = getCountQueryFromEql(eql);
		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		TableEntity table=dao.queryEql(eql);
		return table.getRow(0).getInt("totalcount");
	}
	
	public int getResultSetRowsCount(PreparedEql preparedEql) throws EdiDAOException{
		preparedEql.eql = getCountQueryFromEql(preparedEql.eql);
		EdiDAO dao = DAOUtil.getEdiDAO(appName);
		TableEntity table=dao.queryPreparedEql(preparedEql);
		return table.getRow(0).getInt("totalcount");
	}
	
	/**
	 * 根据查询eql返回记录数查询eql
	 * eql语句的设定，应该根据方言进行设计，下面的设计有问题，临时使用
	 * @param eql
	 * @return
	 */
	private String getCountQueryFromEql(String eql){
		String returnEql="select count(*) totalcount ";
		int fromIndex=eql.indexOf(" from "); 
		log.debug(" fromIndex ="+fromIndex);
		returnEql+=eql.substring(fromIndex);
		log.debug("fromIndex returnEql ="+returnEql); 
		int groupIndex=returnEql.indexOf(" group ");
		log.debug(" groupIndex ="+groupIndex);
		if(groupIndex>0)
			returnEql=returnEql.substring(0, groupIndex);
		log.debug("groupIndex returnEql ="+returnEql);
		int orderIndex=returnEql.indexOf(" order ");
		log.debug(" orderIndex ="+orderIndex);
		if(orderIndex>0)
			returnEql=returnEql.substring(0, orderIndex);
		log.debug("orderIndex returnEql ="+returnEql);
		return returnEql;
	}
}
